package com.supermali.entity.npc;

import com.supermali.creater.MapCreater;
import com.supermali.entity.MapImageAbstract;
import com.supermali.entity.map.hinder.HinderMapAbstract;
import com.supermali.entity.npc.monistor.MonistorAbstract;
import com.supermali.util.IntersectionUtil;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @project super-mali
 * @Date 2021/2/28
 * @Auth yangrui
 **/
public abstract class NPCAbstract extends MapImageAbstract {

    private double ELIPPSE = 4; // 误差范围

    public NPCAbstract(Double x, Double y, MapCreater mapCreater) {
        super(x, y, mapCreater);
    }

    /**
     * 检测碰撞
     * */
    public Set<IntesectDirect> checkCollide(){
        MapCreater creater = getMapCreater();
        Set<IntesectDirect> result = new HashSet<>();
        List<HinderMapAbstract> hinderMapAbstracts = creater.getHinderMapAbstracts();
        for(HinderMapAbstract hinderMapAbstract:hinderMapAbstracts){
            IntesectDirect direct = dealOne(hinderMapAbstract);
            if(direct!=null){
                result.add(direct);
            }
        }
        List<MonistorAbstract> monistorAbstracts = creater.getMonistorAbstracts();
        for(MonistorAbstract monistorAbstract:monistorAbstracts){
            IntesectDirect direct = dealOne(monistorAbstract);
            if(direct!=null){
                result.add(direct);
            }
        }
        for(IntesectDirect k:result){
            MapImageAbstract intesect = k.getIntesect();
            BufferedImage bufferedImage = intesect.getBufferedImage();
            int width = bufferedImage.getWidth();
            int width1 = this.getBufferedImage().getWidth();
            int height = bufferedImage.getHeight();
            int height1 = this.getBufferedImage().getHeight();
            double cy = (intesect.getY()+height+intesect.getY())/2;
            double cx = (intesect.getX()+width+intesect.getX())/2;
            if(k.getDirect()==IntesectDirect.Direct.TOP){
                double y = cy + height/2+1;
                this.setY(y);
            }else if(k.getDirect()==IntesectDirect.Direct.DOWN){
                double y = cy - height/2-height1-1;
                this.setY(y);
            }else if(k.getDirect()==IntesectDirect.Direct.LEFT){
                double x = cx - width/2-width1-1;
                this.setX(x);
            }else if(k.getDirect()==IntesectDirect.Direct.RIGHT){
                double x = cx + width/2+1;
                this.setX(x);
            }
        }
        return result;
    }


    public IntesectDirect dealOne(MapImageAbstract hinderMapAbstract){
        Shape shape = this.getShape();
        Rectangle rectangle = (Rectangle) shape;
        Shape abstractShape = hinderMapAbstract.getShape();
//        boolean intersects = abstractShape.intersects(rectangle);
        boolean intersection = IntersectionUtil.rectrectIntersection((Rectangle) abstractShape, rectangle);
        if(intersection){
            int height1 = this.getBufferedImage().getHeight();
            int width1 = this.getBufferedImage().getWidth();
            int height2 = hinderMapAbstract.getBufferedImage().getHeight();
            int width2 = hinderMapAbstract.getBufferedImage().getWidth();
            double y1 = (this.getY()+height1+this.getY())/2;
            double x1 = (this.getX()+width1+this.getX())/2;
            double y2 = (hinderMapAbstract.getY()+height2+hinderMapAbstract.getY())/2;
            double x2 = (hinderMapAbstract.getX()+width2+hinderMapAbstract.getX())/2;
            if(y1-y2>=(height1+height2)/2-ELIPPSE){
                IntesectDirect direct = new IntesectDirect();
                direct.setDirect(IntesectDirect.Direct.TOP);
                direct.setIntesect(hinderMapAbstract);
                return direct;
            }else if(y2-y1>=(height1+height2)/2-ELIPPSE){
                IntesectDirect direct = new IntesectDirect();
                direct.setDirect(IntesectDirect.Direct.DOWN);
                direct.setIntesect(hinderMapAbstract);
                return direct;
            }else {
                // 接下来就是X轴方向判断
                if(x2-x1>=(width1+width2)/2-ELIPPSE){
                    IntesectDirect direct = new IntesectDirect();
                    direct.setDirect(IntesectDirect.Direct.LEFT);
                    direct.setIntesect(hinderMapAbstract);
                    return direct;
                }else if(x1-x2>=(width1+width2)/2-ELIPPSE) {
                    IntesectDirect direct = new IntesectDirect();
                    direct.setDirect(IntesectDirect.Direct.RIGHT);
                    direct.setIntesect(hinderMapAbstract);
                    return direct;
                }
            }
        }
        return null;
    }
}
